home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / tcoop.arc / TCOOP2.ARC / TXUNIT.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-26  |  6.2 KB  |  231 lines

  1. // Provides low-level screen support through the TxBuff object 
  2. #include <dos.h>
  3. #include "txunit.h"
  4.  
  5. #define True 1
  6. #define False 0
  7.  
  8. TxBuff::TxBuff(TexelPtr T)
  9. // Initializes a TxBuff object. T is a pointer to the texel buffer
  10. // to use or 0 if TxBuff is supposed to allocate its own texel
  11. // buffer. 
  12. {
  13.   Wd = 0; Ht = 0;
  14.   SetRamPtr(T);
  15. }
  16.  
  17. TxBuff::TxBuff(int W, int H, TexelPtr T)
  18. // Initializes a TxBuff object. T is a pointer to the texel buffer
  19. // to use or 0 if TxBuff is supposed to allocate its own texel
  20. // buffer. Then, the width and height are set.
  21. {
  22.   SetRamPtr(T);
  23.   SetSize(W, H);
  24. }
  25.  
  26. void TxBuff::SetRamPtr(TexelPtr T)
  27. // Initializes a TxBuff object. T is a pointer to the texel buffer
  28. // to use or 0 if TxBuff is supposed to allocate its own texel
  29. // buffer. 
  30. {
  31.   if (T) {
  32.      Aliased = True;
  33.      Txram = T;
  34.   }
  35.   else {
  36.      Aliased = False;
  37.      Txram = 0;
  38.   }
  39.   OrgPtr = Txram;
  40. }
  41.  
  42. TxBuff::~TxBuff(void)
  43. // Free texel buffer in TxBuff if object was not aliased 
  44. {
  45.   if (!Aliased) delete[Wd*Ht] Txram;
  46. }
  47.  
  48. TexelPtr TxBuff::TxramAddr(int X, int Y)
  49. // Computes pointer for (X,Y) location relative to Txram 
  50. {
  51.   return Txram + Y*Wd + X;
  52. }
  53.  
  54. TexelPtr TxBuff::RelAddr(int X, int Y)
  55. // Computes pointer for (X,Y) location relative to OrgPtr 
  56. {
  57.   return OrgPtr + Y*Wd + X;
  58. }
  59.  
  60. void TxBuff::SetSize(int W, int H)
  61. // Set size of texel buffer. If not aliased, and the size
  62. // has been set before, don't reallocate memory unless the
  63. // new size is bigger. 
  64. {
  65.   if (!Aliased) { // Want buffer on heap 
  66.      if (!Txram) { // Allocate for first time 
  67.         Txram = new Texel[W*H];
  68.      }
  69.      else if (W*H > Wd*Ht)  { // Reallocate? 
  70.         delete [Wd*Ht] Txram;
  71.         Txram = new Texel[W*H];
  72.      }
  73.      OrgPtr = Txram;
  74.   }
  75.   Wd = W; Ht = H;
  76. }
  77.  
  78. void TxBuff::SetLocn(int X, int Y)
  79. // Set location of OrgPtr--which is the pointer into TxBuff which
  80. // operations such as Fill, FillB, HzWrt and so on, are with
  81. // respect to 
  82. {
  83.   OrgPtr = TxramAddr(X, Y);
  84. }
  85.  
  86. void TxBuff::Swap(int X, int Y, int W, int H, TxBuff *Other, int Xs, int Ys)
  87. // Swaps data between the Other Txbuff, starting as (Xs, Ys)
  88. // and this object's OrgPtr, starting at X,Y, and swapping a region
  89. // of width W, height H. The swap takes place row by row.
  90. // We handle possible memory overlap by reversing the directions
  91. // of the swap, assuming that the only way overlap can occur
  92. // is when we're swapping memory within ourselves. 
  93. {
  94.   int I, J;
  95.   Texel T;
  96.   TexelPtr Dp, Sp;
  97.   Dp = RelAddr(X, Y);
  98.   Sp = Other->RelAddr(Xs, Ys);
  99.   if (FP_OFF(Sp) < FP_OFF(Dp)) { // Might need to switch directions
  100.      for (I=0; I<H; I++) {
  101.        Dp = RelAddr(X, Y+I); 
  102.        Sp = Other->RelAddr(Xs, Ys+I);
  103.        for (J=0; J<W; J++) {
  104.          T = *Dp;
  105.          *Dp++ = *Sp;
  106.          *Sp++ = T;
  107.        }
  108.      }
  109.   }
  110.   else {
  111.      for (I=H-1; I>=0; I--) {
  112.        Dp = RelAddr(X, Y+I) + W;
  113.        Sp = Other->RelAddr(Xs, Ys+I) + W;
  114.        for (J=0; J<W; J++) {
  115.          T = *(--Dp);
  116.          *Dp = *(--Sp);
  117.          *Sp = T;
  118.        }   
  119.      }
  120.   }
  121. }
  122.  
  123. void TxBuff::Xfr(int X, int Y, int W, int H, TxBuff *Other, int Xs, int Ys)
  124. // Transfers data from the Other Txbuff, starting as (Xs, Ys) into
  125. // this object's OrgPtr, starting at X,Y, and transferring a region
  126. // of width W, height H. The transfer takes place row by row.
  127. // We handle possible memory overlap by reversing the directions
  128. // of the transfer, assuming that the only way overlap can occur
  129. // is when we're transferring memory within ourselves. 
  130. {
  131.   int I, J;
  132.   TexelPtr Dp, Sp;
  133.   Dp = RelAddr(X, Y);
  134.   Sp = Other->RelAddr(Xs, Ys);
  135.   if (FP_OFF(Dp) < FP_OFF(Sp)) { // Might need to switch directions
  136.      for (I=0; I<H; I++) {
  137.        Dp = RelAddr(X, Y+I);
  138.        Sp = Other->RelAddr(Xs, Ys+I);
  139.        for (J=0; J<W; J++) *Dp++ = *Sp++;
  140.      }
  141.   }
  142.   else {
  143.     for (I=H-1; I>=0; I--) {
  144.      Dp = RelAddr(X, Y+I) + W;
  145.      Sp = Other->RelAddr(Xs, Ys+I) + W;
  146.      for (J=0; J<W; J++) *(--Dp) = *(--Sp);
  147.     }
  148.   }
  149. }
  150.  
  151. void TxBuff::Scroll(int X, int Y, int W, int H, ScrollDir Sd, int Amt)
  152. // Scroll the text in a specified direction by doing 
  153. // overlapping transfers with Self 
  154. {
  155.   switch(Sd) {
  156.     case UpScroll:    Xfr(X, Y, W, H, this, X, Y+Amt); break;
  157.     case DnScroll:    Xfr(X, Y+Amt, W, H, this, X, Y); break;
  158.     case LeftScroll:  Xfr(X, Y, W, H, this, X+Amt, Y); break;
  159.     case RightScroll: Xfr(X+Amt, Y, W, H, this, X, Y); break;
  160.     default: ; 
  161.   }
  162. }
  163.  
  164. void TxBuff::Fill(int X, int Y, int W, int H, char Ch, char Attr)
  165. // Fill a rectangular region with a particular character and
  166. // attribute. The coordinates are relative to this canvas.
  167. {
  168.   for (int I=0; I<H; I++) {
  169.       TexelPtr Tp = RelAddr(X, Y+I);
  170.       for (int J=0; J<W; J++) {
  171.           Tp->Ch = Ch;
  172.           Tp->Attr = Attr;
  173.           Tp++;
  174.       }
  175.   }
  176. }
  177.  
  178. void TxBuff::FillB(int X, int Y, int W, int H, char Ch, char Opt)
  179. // Fill either the character or the attribute fields in a
  180. // rectangular region. The coordinates are relative to this canvas 
  181. {
  182.   for (int I=0; I<H; I++) {
  183.      char far *P = (char far *)RelAddr(X,Y+I);
  184.      if (Opt) P++; // Skip over char byte
  185.      for (int J=0; J<W; J++) {
  186.          *P = Ch;
  187.          P += 2;
  188.      }
  189.   }
  190. }
  191.  
  192.  
  193. void TxBuff::HzWrt(int X, int Y, char *Str, char Attr, unsigned Cnt)
  194. // Writes to (X,Y) locn (relative to OrgPtr) 
  195. {
  196.   TexelPtr Tp = RelAddr(X, Y);
  197.   for (int I=0; I<Cnt; I++, Tp++) {
  198.       Tp->Ch = *Str++;
  199.       Tp->Attr = Attr;
  200.   } 
  201. }
  202.  
  203. void TxBuff::HzWrtB(int X, int Y, char *Str, unsigned Cnt)
  204. // Writes to (X,Y) locn (relative to OrgPtr) 
  205. {
  206.   char far *P = (char far *)RelAddr(X, Y);
  207.   for (int J=0; J<Cnt; J++) {
  208.       *P = *Str++;
  209.        P += 2;              // Skip over attribute
  210.   } 
  211. }
  212.  
  213. TexelPtr VideoPtr(unsigned &Vmode, unsigned &Vpage)
  214. // Discover what text mode we're in, and return video addr
  215. {
  216.   union REGS Regs;
  217.   unsigned Segment, Offset;
  218.   Regs.h.ah = 15;
  219.   int86(0x10, &Regs, &Regs);
  220.   Vmode = Regs.h.al;  Vpage = Regs.h.bh;
  221.   if (Vmode == 7) Segment = 0xb000; else Segment = 0xb800;
  222.   Offset = Vpage * (unsigned)0x1000;
  223.   return TexelPtr((long(Segment) << 16) | long(Offset));
  224. }
  225.  
  226. TexelPtr VideoPtr(void)
  227. {
  228.   unsigned Vm, Vp;
  229.   return VideoPtr(Vm, Vp);
  230. }
  231.